package com.leha.core.services.imp;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
import com.leha.core.constants.CoreErrorDict;
import com.leha.core.dao.LhUserCustomMapper;
import com.leha.core.dao.LhUserMapper;
import com.leha.core.entity.mybatis.LhUser;
import com.leha.core.entity.mybatis.LhUserExample;
import com.leha.core.entity.vo.UserLoginVO;
import com.leha.core.services.ErrorMessageServices;
import com.leha.core.services.GameServices;
import com.leha.core.services.UserServices;
import me.chanjar.weixin.common.exception.WxErrorException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.ResourceBundle;

import static com.leha.core.constants.CoreErrorDict.GAME_NOT_EXIST;
import static com.leha.core.constants.CoreErrorDict.SYSTEM_ERROR;

@Service
public class UserServicesImpl implements UserServices {
    private static final Integer dayMaxCnt = Integer.valueOf(ResourceBundle.getBundle("config").getString("zzl.dayPlayCnt"));
    private static final Integer shareMaxCnt = Integer.valueOf(ResourceBundle.getBundle("config").getString("zzl.shareMaxCnt"));

    @Autowired
    private GameServices gameServices;
    @Autowired
    private LhUserMapper userMapper;
    @Autowired
    private LhUserCustomMapper userCustomMapper;
    @Autowired
    private ErrorMessageServices errorMessageServices;

    private static final Logger LOG = LoggerFactory.getLogger(UserServicesImpl.class);

    @Override
    public UserLoginVO SaveInfo(Integer gameId, Integer uid, String sessionKey, String encryptedData, String iv) {
        try {
            LhUserExample ex = new LhUserExample();
            LhUser user = userMapper.selectByPrimaryKey(uid);
            WxMaService wxService = gameServices.getGameServices(gameId);
            WxMaUserInfo userInfo = wxService.getUserService().getUserInfo(sessionKey, encryptedData, iv);
            user.setAvatarUrl(userInfo.getAvatarUrl());
            user.setNickname(userInfo.getNickName());
            user.setGameId(1);
            userMapper.updateByPrimaryKeySelective(user);
            return new UserLoginVO(user,
                   UserCanPlayTimes(user.getUid()),
                   userCustomMapper.getUserRewardCnt(user.getUid()));
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
            errorMessageServices.setError(SYSTEM_ERROR);
            return null;
        }
    }

    private UserLoginVO enterRetry(Integer gameId, String code, Integer times) {
        if(times<0) return null;
        try {
            WxMaService wxService = gameServices.getGameServices(gameId);
            if(wxService==null) {
                errorMessageServices.setError(GAME_NOT_EXIST);
                return null;
            }
            WxMaJscode2SessionResult session = wxService.getUserService().getSessionInfo(code);
            LOG.info(session.getSessionKey());
            LOG.info(session.getOpenid());
            LhUserExample ex = new LhUserExample();
            ex.createCriteria().andOpenidEqualTo(session.getOpenid());
            List<LhUser> user = userMapper.selectByExample(ex);
            if(user.size()==0) {
                LhUser newUser = new LhUser();
                newUser.setOpenid(session.getOpenid());
                newUser.setGameId(gameId);
                userMapper.insertSelective(newUser);
                return new UserLoginVO(newUser, dayMaxCnt, 0, session.getSessionKey());
            } else {
                LhUser u = user.get(0);
                return new UserLoginVO(u,
                        UserCanPlayTimes(u.getUid()),
                        userCustomMapper.getUserRewardCnt(u.getUid()), session.getSessionKey());
            }
        } catch (Exception e) {
            return enterRetry(gameId, code, times-1);
        }
    }
    @Override
    public UserLoginVO enter(Integer gameId, String code) {
        return enterRetry(gameId, code, 3);
    }

    @Override
    public Integer UserCanPlayTimes(Integer uid) {
        Integer shareTimes = userCustomMapper.getShareTimes(uid);
        Integer playCnt = userCustomMapper.getUserPlayCnt(uid);
        Integer rr = dayMaxCnt - playCnt + (shareTimes > shareMaxCnt ? shareMaxCnt: shareTimes);
        return rr > 0 ? rr : 0;
    }

    @Override
    public UserLoginVO getUserInfo(Integer uid) {
        LhUser u = userMapper.selectByPrimaryKey(uid);
        if(u==null) {
            errorMessageServices.setError(CoreErrorDict.RESULT_ERROR);
            return null;
        }
        return new UserLoginVO(u,
                    UserCanPlayTimes(u.getUid()),
                    userCustomMapper.getUserRewardCnt(u.getUid()), null);
    }
}
